package com.youlu.campus.service.visitor;

import com.alibaba.fastjson.JSON;
//import com.ctrip.framework.apollo.Config;
//import com.ctrip.framework.apollo.ConfigService;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.base.user.WechatLogoAuth;
import com.youlu.campus.base.user.WechatMiniBase;
import com.youlu.campus.entity.*;
import com.youlu.campus.entity.VO.req.CreatedUserInfoExtendCommand;
import com.youlu.campus.entity.VO.res.MyInfoResponse;
import com.youlu.campus.entity.VO.res.UserInfoExtendRes;
import com.youlu.campus.entity.ca.UserCa;
import com.youlu.campus.entity.commission.UserParticipateDistributorChannelInfo;
import com.youlu.campus.entity.domain.UserPointsDomain;
import com.youlu.campus.entity.douyin.DouYinMiniUserPO;
import com.youlu.campus.entity.english.vo.request.UserCompetitionFeeQuery;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.service.activity.UserParticipateActivityInfoService;
import com.youlu.campus.service.ca.CaPinYinService;
import com.youlu.campus.service.ca.UserCaService;
import com.youlu.campus.service.douyin.DouYinUserService;
import com.youlu.campus.service.commission.UserParticipateDistributorChannelInfoService;
import com.youlu.campus.service.point.UserPointTaskInfoService;
import com.youlu.campus.service.qq.QQMiniUserService;
import com.youlu.campus.service.ranking.UserPointRankingService;
import com.youlu.campus.service.system.SystemApolloConfigService;
import com.youlu.campus.service.wechat.WechatMiniService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserInfoExtendService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private final static String CACHE_USER = "campus:userinfo:ext:%s";

    private final static String LOCK_USER_UPDATE = "campus:userinfo:%s:%s:%s";

    private final static String CACHE_USER_ADDRESS = "campus:userinfo:address:%s";

    @Lazy
    @Autowired
    private UserCaService userCaService;

    @Autowired
    private UserPointsService userPointsService;

    @Lazy
    @Autowired
    private UserParticipateActivityInfoService userParticipateActivityInfoService;

    @Autowired
    private UserPointTaskInfoService userPointTaskInfoService;

    @Autowired
    private UserPointRankingService userPointRankingService;

    @Autowired
    private QQMiniUserService qqMiniUserService;

    @Autowired
    @Lazy
    private WechatMiniService wechatMiniService;

    @Lazy
    @Autowired
    private CaPinYinService caPinYinService;

    @Autowired
    @Lazy
    private DouYinUserService douYinUserService;

    @Autowired
    private UserParticipateDistributorChannelInfoService userParticipateDistributorChannelInfoService;
    @Autowired
    private SystemApolloConfigService systemApolloConfigService;

    public static void main(String[] args) {
        System.out.println("18571612388".replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
    }

    public void updateByUserId(UserPO currentUser, UserInfoExtend updateUserInfoExtend) {
        UserInfoExtend userInfoExtend = this.findByUserIdAndAppId(currentUser);
        if (Objects.isNull(userInfoExtend)) {
            throw new BusinessException("当前用户不存在");
        }
        String name = updateUserInfoExtend.getName();
        if (StringUtils.isNotBlank(name)) {
            if (updateUserInfoExtend.getUpdateNameCount() > 1) {
                throw new BusinessException("对不起，姓名只可修改一次");
            }
        }
        String lockKey = String.format(LOCK_USER_UPDATE, currentUser.getId(), currentUser.getAppId(),
                currentUser.getCurrentPlatform());
        Boolean existKey = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 2L, TimeUnit.SECONDS);
        if (Objects.nonNull(existKey) && !existKey) {
            throw new BusinessException("对不起，不能重复提交，稍后重试");
        }
        Update update = new Update();
        if (StringUtils.isNotBlank(name)) {
            update.set("name", name);
            update.inc("updateNameCount", 1);
        }
        String universityId = updateUserInfoExtend.getUniversityId();
        String universityName = updateUserInfoExtend.getUniversityName();
        if (StringUtils.isNotBlank(universityId) && StringUtils.isNotBlank(universityName)) {
            update.set("universityId", universityId);
            update.set("universityName", universityName);
        }
        if (StringUtils.isNotBlank(updateUserInfoExtend.getGrade())) {
            update.set("grade", updateUserInfoExtend.getGrade());
        }
        if (StringUtils.isNotBlank(updateUserInfoExtend.getMobile())) {
            update.set("mobile", updateUserInfoExtend.getMobile());
        }
        String majorId = updateUserInfoExtend.getMajorId();
        String majorName = updateUserInfoExtend.getMajorName();
        if (StringUtils.isNotBlank(majorId) && StringUtils.isNotBlank(majorName)) {
            update.set("majorId", majorId);
            update.set("majorName", majorName);
        }
        Date now = new Date();
        update.set("updatedTime", now);
        Query queryByUser = getQueryByUser(currentUser);
        FindAndModifyOptions findAndModifyOptions = FindAndModifyOptions.options();
        findAndModifyOptions.returnNew(Boolean.TRUE);
        findAndModifyOptions.upsert(Boolean.TRUE);
        UserInfoExtend userInfoExtendModify = this.mongoTemplate.findAndModify(queryByUser, update,
                findAndModifyOptions, UserInfoExtend.class);
        if (Objects.nonNull(userInfoExtendModify)) {
            //更新用户信息
            this.userCaService.updateByUserId(userInfoExtendModify);
            UserParticipateActivityInfo userParticipateActivityInfo = new UserParticipateActivityInfo();
            userParticipateActivityInfo.setUserId(currentUser.getId());
            userParticipateActivityInfo.setUniversityId(userInfoExtend.getUniversityId());
            userParticipateActivityInfo.setUniversityName(userInfoExtend.getUniversityName());
            userParticipateActivityInfo.setMobile(userInfoExtend.getMobile());
            userParticipateActivityInfo.setName(userInfoExtend.getName());
            userParticipateActivityInfo.setNickName(userInfoExtend.getNickName());
            userParticipateActivityInfo.setGrade(userInfoExtend.getGrade());
            userParticipateActivityInfo.setJoined(Boolean.TRUE);
            userParticipateActivityInfo.setPassed(Boolean.TRUE);
            userParticipateActivityInfoService.saveOrUpdate(userParticipateActivityInfo);
            //增加积分
            userInfoExtendModify.checkUserInfoComplete();
            Boolean userInfoComplete = userInfoExtendModify.getUserInfoComplete();
            if (!userInfoExtendModify.getPerfectInfoAddPoint() && !userInfoComplete) {
                update = new Update();
                update.set("perfectInfoAddPoint", Boolean.TRUE);
                UpdateResult updateResult = this.mongoTemplate.updateFirst(queryByUser, update, UserInfoExtend.class);
                if (updateResult.getModifiedCount() > 0) {//添加更新完善用户信息任务
                    UserPointTaskInfo userPointTaskInfo = new UserPointTaskInfo();
                    userPointTaskInfo.setUserId(currentUser.getId());
                    userPointTaskInfo.setAppId(currentUser.getAppId());
                    userPointTaskInfo.setPlatform(currentUser.getCurrentPlatform());
                    userPointTaskInfo.setDayTime(now);
                    userPointTaskInfo.setDoneTime(now);
                    userPointTaskInfo.setTaskBizType(TaskBizType.PERFECT_INFO);
                    userPointTaskInfo.setQuantity(20);
                    userPointTaskInfo.setStatus(1);
                    userPointTaskInfoService.create(userPointTaskInfo);
                    UserPointsDetail detail = new UserPointsDetail();
                    detail.setUserId(currentUser.getId());
                    detail.setAction("add");
                    detail.setBizDesc("完善信息");
                    detail.setBizType("perfect_info");
                    detail.setOptDate(now);
                    detail.setPoints(20);
                    detail.setAppId(currentUser.getAppId());
                    detail.setPlatform(currentUser.getCurrentPlatform());
                    detail.setComments("完善信息获得20积分");
                    userPointsService.addPoint(detail);
                    userPointRankingService.updatePoint(currentUser, "", 20);
                }
            }

        }
    }

    public UserInfoExtend getUserInfoByActivityId(String activityId, UserPO currentUser) {
        UserInfoExtend user = this.findByUserId(currentUser.getId());
        if (Objects.isNull(user)) {
            return null;
        }
        ActivityInfo activityInfo = this.mongoTemplate.findById(activityId, ActivityInfo.class);
        user.setDigitalCaType(activityInfo.getDigitalCaType());
        if (ActivityInfo.DIGITAL_ENGLISH_CA.equals(activityInfo.getDigitalCaType())) {
            if (StringUtils.isNotBlank(user.getName()) && StringUtils.isBlank(user.getEnName())) {
                String pinYinName = caPinYinService.getPinYinNameByUserId(activityId, user);
                if (StringUtils.isNotBlank(pinYinName)) {
                    user.setEnName(pinYinName);
                    this.mongoTemplate.save(user);
                    UserParticipateActivityInfo userParticipateActivityInfo = new UserParticipateActivityInfo();
                    userParticipateActivityInfo.setEnName(pinYinName);
                    userParticipateActivityInfo.setUserId(currentUser.getId());
                    userParticipateActivityInfo.setActivityId(activityId);
                    userParticipateActivityInfo.setJoined(Boolean.TRUE);
                    userParticipateActivityInfoService.saveOrUpdate(userParticipateActivityInfo);
                }
            }
        }
        if (StringUtils.isNotBlank(user.getUniversityId())) {
            UniversityInfo universityInfo = this.mongoTemplate.findById(user.getUniversityId(), UniversityInfo.class);
            if (Objects.nonNull(universityInfo)) {
                user.setEnUniversityName(universityInfo.getEnName());
            }
        }
        return user;
    }

    public UserInfoExtend findUserInfoByUserId(UserPO currentUser) {
        UserInfoExtend userInfoExtend = this.findByUserIdAndAppId(currentUser);
        if (Objects.isNull(userInfoExtend)) {
            userInfoExtend = new UserInfoExtend();
        }
        userInfoExtend.setId(currentUser.getId());
        userInfoExtend.setNickName(currentUser.getNickName());
        userInfoExtend.setAvatarUrl(currentUser.getAvatarUrl());
        if (StringUtils.isNotBlank(userInfoExtend.getMobile())) {
            userInfoExtend.setMobile(userInfoExtend.getMobile());
        }
        //验证信息是否完整
        userInfoExtend.checkUserInfoComplete();

        userInfoExtend.setOpenId(currentUser.getOpenId());
        //微信小程序
        if ("wechat-mini".equals(currentUser.getCurrentPlatform())) {
            WechatMiniUserPO wechatMiniUser = wechatMiniService.findByOpenId(currentUser.getAppId(),
                    currentUser.getOpenId());
            if (Objects.nonNull(wechatMiniUser)) {
                String mobile = StringUtils.isNotBlank(wechatMiniUser.getMobile()) ? wechatMiniUser.getMobile() : currentUser.getMobile();
                wechatMiniUser.checkNickNameAndAvatarUrl();
                userInfoExtend.setBinded(wechatMiniUser.getBinded());
                userInfoExtend.setMobile(StringUtils.isNotBlank(mobile) ? mobile : userInfoExtend.getMobile());
            }
//            Config config = ConfigService.getAppConfig();
//            String cnf = config.getProperty("wechat.mini.base", "{}");
//            WechatMiniBase wechatMiniBase = JSON.parseObject(cnf, WechatMiniBase.class);
            SystemApolloConfig systemApolloConfig = systemApolloConfigService.find();
            WechatMiniBase wechatMiniBase = systemApolloConfig.getWechatMiniBase();
            if ("v1".equals(wechatMiniBase.getVersion())) {
                userInfoExtend.setBinded(true);
            }
        } else if ("douyin-mini".equals(currentUser.getCurrentPlatform())) {
            userInfoExtend.setPlatform("douyin-mini");
            DouYinMiniUserPO miniUserPO = douYinUserService.findByOpenId(currentUser.getAppId(), currentUser.getOpenId());
            if (Objects.nonNull(miniUserPO)) {
                String mobile = StringUtils.isNotBlank(miniUserPO.getMobile()) ? miniUserPO.getMobile() : currentUser.getMobile();
                miniUserPO.checkNickNameAndAvatarUrl();
                userInfoExtend.setBinded(miniUserPO.getBinded());
                userInfoExtend.setMobile(StringUtils.isNotBlank(mobile) ? mobile : userInfoExtend.getMobile());
            }
        } else {
            QQMiniUserPO qqMiniUser = qqMiniUserService.queryUserByOpenId(currentUser.getAppId(),
                    currentUser.getOpenId());
            if (Objects.nonNull(qqMiniUser)) {
                qqMiniUser.checkNickNameAndAvatarUrl();
                userInfoExtend.setBinded(qqMiniUser.getBinded());
            }
        }

        return userInfoExtend;
    }

    public UserInfoExtend findByUserIdAndAppId(UserPO currentUser) {
        Query query = getQueryByUser(currentUser);
        return this.mongoTemplate.findOne(query, UserInfoExtend.class);
    }

    private Query getQueryByUser(UserPO currentUser) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(currentUser.getId()));
        //query.addCriteria(Criteria.where("appId").is(currentUser.getAppId()));
        //query.addCriteria(Criteria.where("platform").is(currentUser.getCurrentPlatform()));
        return query;
    }

    public UserInfoExtend findById(String id) {
        return this.mongoTemplate.findById(id, UserInfoExtend.class);
    }

    public void updateUserInfoExt(UserInfoExtend userInfoExtend) {
        if (StringUtils.isBlank(userInfoExtend.getId())) {
            return;
        }
        UserInfoExtend userInfoExtendExist = this.mongoTemplate.findById(userInfoExtend.getId(), UserInfoExtend.class);
        if (Objects.isNull(userInfoExtendExist)) {
            log.error("主键ID不存在 - >{}", userInfoExtend.getId());
            return;
        }
        userInfoExtend.setId(userInfoExtendExist.getId());
        userInfoExtend.setCreatedTime(userInfoExtendExist.getCreatedTime());
        userInfoExtend.setUpdatedTime(new Date());
        this.mongoTemplate.save(userInfoExtend);
        userCaService.updateByUserId(userInfoExtend);
    }


    public Page<UserInfoExtendRes> list(UserCompetitionFeeQuery userQuery) {
        String mobile = userQuery.getMobile();
        String universityId = userQuery.getUniversityId();
        Query query = new Query();
        boolean choiced = false;
        if (StringUtils.isNotBlank(universityId)) {
            query.addCriteria(Criteria.where("universityId").is(universityId));
            choiced = true;
        }
        if (StringUtils.isNotBlank(mobile)) {
            query.addCriteria(Criteria.where("mobile").is(mobile));
            choiced = true;
        }
        if (StringUtils.isNotBlank(userQuery.getName())) {
            Pattern pattern = Pattern.compile("^.*" + userQuery.getName() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("name").regex(pattern));
            choiced = true;
        }
        PageRequest pageRequest = PageRequest.of(userQuery.getPageNo() - 1, userQuery.getPageSize());
        Long count;
        if (choiced) {
            count = this.mongoTemplate.count(query, UserInfoExtend.class);
        } else {
            count = 10000L;
        }
        if (count.compareTo(0L) == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
        }
        query.with(Sort.by(Sort.Direction.DESC, "createdTime"));
        List<UserInfoExtend> list = this.mongoTemplate.find(query.with(pageRequest), UserInfoExtend.class);
        List<UserInfoExtendRes> extendResList = list.stream().map(userInfoExtend -> {
            UserInfoExtendRes userInfoExtendRes = new UserInfoExtendRes();
            BeanUtils.copyProperties(userInfoExtend, userInfoExtendRes);
            userInfoExtendRes.setId(userInfoExtend.getId());
            UserPointsDomain userPointsDomain = userPointsService.getMyPoint(userInfoExtend.getUserId(),
                    userQuery.getAppId());
            if (Objects.nonNull(userPointsDomain)) {
                userInfoExtendRes.setPoint(userPointsDomain.getPoint());
            }
            return userInfoExtendRes;
        }).collect(Collectors.toList());
        return PageableExecutionUtils.getPage(extendResList, pageRequest, () -> count);
    }


    public UserInfoExtend findByUserId(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        return this.mongoTemplate.findOne(query, UserInfoExtend.class);
    }

    public UserInfoSignDetail findUserSignInfo(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        return this.mongoTemplate.findOne(query, UserInfoSignDetail.class);
    }

    public void addUserInfoExt(CreatedUserInfoExtendCommand command) {
        UserPO currentUser = command.getCurrentUser();
        currentUser.setOpenId(currentUser.getOpenId());
        currentUser.setMobile(command.getMobile());
        currentUser.setName(command.getName());
        currentUser.setUniversityId(command.getUniversityId());
        currentUser.setGrade(command.getGrade());
        currentUser.setUniversityName(command.getUniversityName());
        currentUser.setAvatarUrl(currentUser.getAvatarUrl());
        currentUser.setNickName(currentUser.getNickName());
        currentUser.setCreatedTime(new Date());
        currentUser.setAppId(currentUser.getAppId());
        currentUser.setMajorId(command.getMajorId());
        currentUser.setMajorName(command.getMajorName());
        currentUser.setH5SignUp(Boolean.TRUE);
        this.saveOrUpdate(currentUser);
        if (command.getType() == 1) {
            UserCa userCa = new UserCa();
            userCa.setUserId(currentUser.getId());
            userCa.setActivityId(command.getActivityId());
            userCa.setCaType(command.getCaType());
            userCa.setCaLevel(command.getCaLevel());
            userCa.setGrade(currentUser.getGrade());
            userCa.setName(currentUser.getName());
            userCa.setUniversityId(currentUser.getUniversityId());
            userCa.setUniversityName(currentUser.getUniversityName());
            userCa.setMobile(currentUser.getMobile());
            userCa.setPlatform(currentUser.getCurrentPlatform());
            userCa.setAppId(currentUser.getAppId());
            userCaService.create(userCa);
        }
        UserParticipateActivityInfo existMobile = userParticipateActivityInfoService.findByMobile(command.getActivityId(), command.getMobile(), Boolean.TRUE);
        if (Objects.nonNull(existMobile)) {
            log.error(":>>> 用户已经报名活动,{},{}", command.getActivityId(), command.getMobile());
            throw new BusinessException("该手机号已报名当前活动，请更换手机号1");
        }
        //购买新增报名信息
        UserParticipateActivityInfo userParticipateActivityInfo =
                this.userParticipateActivityInfoService.findByUserIdActivityId(currentUser.getId(),
                        command.getActivityId());
        if (Objects.isNull(userParticipateActivityInfo)) {
            log.error("【用户参与活动】用户->{}参与活动-> {}答题未查询到报名信息", command.getMobile(), command.getActivityId());
            userParticipateActivityInfo = new UserParticipateActivityInfo();
        }
        userParticipateActivityInfo.setActivityId(command.getActivityId());
        userParticipateActivityInfo.setUserId(currentUser.getId());
        userParticipateActivityInfo.setUniversityId(currentUser.getUniversityId());
        userParticipateActivityInfo.setUniversityName(currentUser.getUniversityName());
        userParticipateActivityInfo.setMobile(currentUser.getMobile());
        userParticipateActivityInfo.setName(currentUser.getName());
        userParticipateActivityInfo.setGrade(currentUser.getGrade());
        userParticipateActivityInfo.setNickName(currentUser.getNickName());
        userParticipateActivityInfo.setJoined(Boolean.TRUE);
        userParticipateActivityInfo.setPassed(Boolean.TRUE);
        userParticipateActivityInfo.setOpenId(currentUser.getOpenId());
        userParticipateActivityInfo.setAppId(currentUser.getAppId());
        userParticipateActivityInfo.setUnionId(currentUser.getUnionId());
        userParticipateActivityInfo.setFromMyPoint(command.getFromMyPoint());
        userParticipateActivityInfo.setAvatarUrl(currentUser.getAvatarUrl());
        userParticipateActivityInfo.setActivityChannelId(command.getActivityChannelId());
        userParticipateActivityInfoService.saveOrUpdate(userParticipateActivityInfo);
        if (StringUtils.isNotBlank(command.getActivityChannelId())) {
            UserParticipateDistributorChannelInfo updateDistributorChannelInfo = new UserParticipateDistributorChannelInfo();
            BeanUtils.copyProperties(userParticipateActivityInfo, updateDistributorChannelInfo);
            updateDistributorChannelInfo.setId(null);
            updateDistributorChannelInfo.setActivityChannelId(command.getActivityChannelId());
            userParticipateDistributorChannelInfoService.save(updateDistributorChannelInfo);
        }

    }

    public Boolean existByUserId(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        return this.mongoTemplate.exists(query, UserInfoExtend.class);
    }

    public void saveOrUpdate(UserPO currentUser) {
        if (Objects.isNull(currentUser)) {
            return;
        }
        Query query = getQueryByUser(currentUser);
        Update update = new Update();
        Date now = new Date();
        boolean exists = this.mongoTemplate.exists(query, UserInfoExtend.class);
        if (!exists) {
            update.set("createdTime", now);
        } else {
            update.set("updatedTime", now);
        }
        if (StringUtils.isNotBlank(currentUser.getMobile())) {
            update.set("mobile", currentUser.getMobile());
        }
        if (StringUtils.isNotBlank(currentUser.getMobile())) {
            update.set("mobile", currentUser.getMobile());
        }
        if (StringUtils.isNotBlank(currentUser.getName())) {
            update.set("name", currentUser.getName());
        }
        if (StringUtils.isNotBlank(currentUser.getUniversityName())) {
            update.set("universityName", currentUser.getUniversityName());
        }
        if (StringUtils.isNotBlank(currentUser.getUniversityId())) {
            update.set("universityId", currentUser.getUniversityId());
        }
        if (StringUtils.isNotBlank(currentUser.getAvatarUrl())) {
            update.set("avatarUrl", currentUser.getAvatarUrl());
        }
        if (StringUtils.isNotBlank(currentUser.getNickName())) {
            update.set("nickName", currentUser.getNickName());
        }
        if (StringUtils.isNotBlank(currentUser.getOpenId())) {
            update.set("openId", currentUser.getOpenId());
        }

        if (StringUtils.isNotBlank(currentUser.getProvince())) {
            update.set("province", currentUser.getProvince());
        }

        if (StringUtils.isNotBlank(currentUser.getArea())) {
            update.set("area", currentUser.getArea());
        }
        if (StringUtils.isNotBlank(currentUser.getCity())) {
            update.set("city", currentUser.getCity());
        }

        if (StringUtils.isNotBlank(currentUser.getFullAddress())) {
            update.set("address", currentUser.getFullAddress());
        }
        if (StringUtils.isNotBlank(currentUser.getReceiveName())) {
            update.set("receiveName", currentUser.getReceiveName());
        }
        if (StringUtils.isNotBlank(currentUser.getReceiveMobile())) {
            update.set("receiveMobile", currentUser.getReceiveMobile());
        }
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(Boolean.TRUE);
        findAndModifyOptions.upsert(Boolean.TRUE);
        UserInfoExtend userModify = this.mongoTemplate.findAndModify(query, update, findAndModifyOptions,
                UserInfoExtend.class);
        putUserAddressCache(userModify);
        //deleteUserAddressCache(currentUser);
        if (Objects.nonNull(userModify)) {
            if (!currentUser.getH5SignUp()) {//H5活动答题报名无需在更新当前报名表
                UserParticipateActivityInfo userParticipateActivityInfo = new UserParticipateActivityInfo();
                userParticipateActivityInfo.setUserId(currentUser.getId());
                userParticipateActivityInfo.setAppId(currentUser.getAppId());
                userParticipateActivityInfo.setNickName(userModify.getNickName());
                userParticipateActivityInfo.setMobile(userModify.getMobile());
                userParticipateActivityInfo.setUniversityId(userModify.getUniversityId());
                userParticipateActivityInfo.setUniversityName(userModify.getUniversityName());
                userParticipateActivityInfo.setPlatform(currentUser.getCurrentPlatform());
                userParticipateActivityInfo.setAvatarUrl(currentUser.getAvatarUrl());
                userParticipateActivityInfo.setOpenId(currentUser.getOpenId());
                userParticipateActivityInfo.setUnionId(currentUser.getUnionId());
                userParticipateActivityInfo.setJoined(Boolean.TRUE);
                userParticipateActivityInfo.setEnName(currentUser.getEnName());
                this.userParticipateActivityInfoService.saveOrUpdate(userParticipateActivityInfo);
            }

        }
    }

    public UserInfoExtend findCacheUserByUserId(UserPO currentUser) {
        log.info("[获取用户地址缓存] userId - >{}", currentUser.getId());
        String key = String.format(CACHE_USER_ADDRESS, currentUser.getId());
        String cacheUserInfo = this.redisTemplate.opsForValue().get(key);
        if (StringUtils.isNotBlank(cacheUserInfo)) {
            return JSON.parseObject(cacheUserInfo, UserInfoExtend.class);
        }
        return this.findByUserId(currentUser.getId());
    }

    public void deleteUserAddressCache(UserPO currentUser) {
        log.info("[清除用户地址缓存] userId - >{}", currentUser.getId());
        String key = String.format(CACHE_USER_ADDRESS, currentUser.getId());
        this.redisTemplate.delete(key);
    }

    public void putUserAddressCache(UserInfoExtend saveUser) {
        if (Objects.isNull(saveUser)) {
            log.warn("[保存用户地址缓存] user is null");
            return;
        }
        log.info("[保存用户地址缓存] userId - >{}", saveUser.getId());
        String key = String.format(CACHE_USER_ADDRESS, saveUser.getUserId());
        this.redisTemplate.opsForValue().set(key, JSON.toJSONString(saveUser), 2L, TimeUnit.MINUTES);
    }

    public Boolean deleteByUserId(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        return this.mongoTemplate.remove(query, UserInfoExtend.class).getDeletedCount() > 0 ? true : false;
    }

    @Async
    public void updateAddressInfoByUserId(UserInfoExtend saveUser, String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        Update update = new Update();
        boolean toUpdate = false;
        if (StringUtils.isNotBlank(saveUser.getProvince())) {
            update.set("province", saveUser.getProvince());
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(saveUser.getCity())) {
            update.set("city", saveUser.getCity());
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(saveUser.getArea())) {
            update.set("area", saveUser.getArea());
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(saveUser.getAddress())) {
            update.set("address", saveUser.getAddress());
            toUpdate = true;
        }
        if (toUpdate) {
            update.set("updatedTime", new Date());
            UpdateResult updateResult = mongoTemplate.updateFirst(query, update, UserInfoExtend.class);
            if(updateResult.getModifiedCount()>0){
                UserPO u = new UserPO();
                u.setId(userId);
                deleteUserAddressCache(u);
            }
        }
        return;
    }


}
